home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1995 / 6 / 02 / patch-work / patchutil.c < prev    next >
C/C++ Source or Header  |  1995-06-01  |  3KB  |  149 lines

  1. /*
  2. ** PatchUtil.c von Patrick Ohly
  3. ** unterstützende Funktionen für Patches
  4. ** © 1994 Patrick Ohly
  5. */
  6.  
  7. #include <dos/dosextens.h>
  8.  
  9. #ifdef _DCC
  10. #include <clib/exec_protos.h>
  11. #else
  12. #include <proto/exec.h>
  13. #endif
  14.  
  15. #include <exec/memory.h>
  16. #include <exec/execbase.h>
  17. #include "PatchUtil.h"
  18.  
  19. extern struct ExecBase *SysBase;
  20.  
  21. /* Werte des Assembler-Befehls JMP */
  22. #define JMP_CMD 0x4EF9
  23.  
  24. /* Aufbau der Assembler-Sprungbefehle: */
  25. #define JMP 0
  26. #define JMP_ADDR 1 /* ULONG */
  27. /* nur bei alter dos.library verwendet:
  28. ** erst D0 auf Funktions-abhängigen Wert setzen,
  29. ** dann DOS-dispatcher anspringen
  30. */
  31. #define MOVEQ 3
  32. #define JMP_DOS 4
  33. #define JMP_DOS_ADDR 5 /* ULONG */
  34. #define BUFFER_SIZE 7
  35.  
  36. /*
  37. ** SafeSetFunction():
  38. ** Funktion: änderte einen Library-Vektor auf neue Funktion um
  39. **
  40. ** Argumente: library_base - zu patchende Library
  41. **            lvo          - Offset der zu patchenden Funktion
  42. **            new_function - die eigene Funktion
  43. **            handle       - Zeiger auf Langwort
  44. ** Ergebnis:  old_function - Zeiger auf alte Funktion oder NULL für Fehler
  45. **            handle       - wird für RemoveFunction() auf Zeiger
  46. **                           des Sprungbefehls gesetzt
  47. */
  48.  
  49. APTR SafeSetFunction(
  50.    struct Library *library_base,
  51.    LONG offset,
  52.    APTR new_function,
  53.    APTR *handle)
  54. {
  55.     UWORD *asm_buffer;
  56.     APTR result = NULL;
  57.  
  58.     if(asm_buffer = AllocMem(2 * BUFFER_SIZE, MEMF_CLEAR|MEMF_PUBLIC))
  59.     {
  60.         ULONG current_function;
  61.         UWORD *vector;
  62.         BOOL standard_lvo;
  63.  
  64.         *handle = asm_buffer;
  65.  
  66.         Disable();
  67.  
  68.         vector = (UWORD *)(((ULONG)library_base) + offset);
  69.  
  70.         /* Standard- und DOS-Format unterstützen  */
  71.         standard_lvo = (vector[0] == JMP_CMD);
  72.  
  73.         /* JMP- bzw. BRA-Zieladresse ermitteln */
  74.         if(standard_lvo)
  75.             current_function = *((ULONG *)&vector[1]);
  76.         else
  77.             current_function = (ULONG)vector +
  78.                                vector[2] + 4;
  79.  
  80.         /* eigene Funktion in asm_buffer eintragen */
  81.         asm_buffer[JMP]                   = JMP_CMD;
  82.         *((APTR *)&asm_buffer[JMP_ADDR]) = new_function;
  83.         /* alten Inhalt retten */
  84.         if(standard_lvo)
  85.             result = (APTR)current_function;
  86.         else
  87.         {
  88.             /* alten DOS-Aufruf nachstellen */
  89.             /* moveq #?,d0 */
  90.             asm_buffer[MOVEQ]   = vector[0];
  91.             asm_buffer[JMP_DOS] = JMP_CMD;
  92.             *((ULONG *)&asm_buffer[JMP_DOS_ADDR]) =
  93.                                   current_function;
  94.             result = &asm_buffer[MOVEQ];
  95.         }
  96.  
  97.         /* neuen Zeiger in LVO eintragen */
  98.         vector[0] = JMP_CMD;
  99.         *((ULONG *)&vector[1]) = (ULONG)asm_buffer;
  100.  
  101.         if(SysBase->LibNode.lib_Version >= 36)
  102.             CacheClearU();
  103.  
  104.         /* Library neu berechnen */
  105.         library_base->lib_Flags |= LIBF_CHANGED;
  106.         SumLibrary(library_base);
  107.  
  108.         Enable();
  109.     }
  110.  
  111.     return(result);
  112. }
  113.  
  114. /*
  115. ** RemoveFunction()
  116. ** Funktion: macht SafeSetFunction() rückgängig
  117. **
  118. ** Argumente: old_function - der Funktionswert, der zurückgeschrieben wird
  119. **            handle       - der von SafeSetFunction() gesetzte Wert
  120. */
  121.  
  122. VOID RemoveFunction(APTR old_function, APTR handle)
  123. {
  124.     Disable();
  125.  
  126.     /* alten Wert zurückschreiben */
  127.     *((APTR *)&(((UWORD *)handle)[JMP_ADDR])) = old_function;
  128.  
  129.     if(SysBase->LibNode.lib_Version >= 36)
  130.         CacheClearU();
  131.  
  132.     Enable();
  133. }
  134.  
  135. /*
  136. ** IsProcess:
  137. ** Funktion: testet auf Process
  138. ** Ergebnis: TRUE zurück, wenn von einem Prozeß aufgerufen,
  139. **           ansonsten FALSE
  140. */
  141. BOOL IsProcess(VOID)
  142. {
  143.    struct Task *my_task;
  144.  
  145.    my_task = FindTask(NULL);
  146.    return((BOOL)
  147.          (my_task->tc_Node.ln_Type == NT_PROCESS));
  148. }
  149.